iT邦幫忙

2024 iThome 鐵人賽

DAY 2
0
佛心分享-刷題不只是刷題

Leecode刷題系列 第 7

D8:Q38Count and Say

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20240923/20169309XlQQMCBlvD.png這題要生成 "Count and Say" 序列的第 n 個數字,再根據前個數字來計算題目要求:
生成第 n 個數字的 Count and Say 序列,第一個數字固定 "1",之後的每個數字都是基於前個數字的 Run-length encoding (也就是計數和描述前個數字的字符)具體說,就是每當一個字符連續出現時,需要記錄該字符出現的次數,然後按「次數+字符」的順序來建新數字。
解題思路:
基礎案例,如果 n = 1 時,結果為 "1",這是整個問題的基本情況。
遞迴生成,每個序列的生成基於前個序列,第 n 個數字是對 n-1 個數字的「Run-length encoding」
例如:
countAndSay(1) = "1"
countAndSay(2) = "11" ("1" 的描述是「一個 1」)
countAndSay(3) = "21" ("11" 的描述是「兩個 1」)
countAndSay(4) = "1211" ("21" 的描述是「一個 2、一個 1」)
處理連續字符:
造新的數字時,需要逐個遍歷當前數字,記錄連續相同字符的次數,再把它轉成「次數+字符」的格式。
循環生成,從 countAndSay(1) 開始,一直生成到 countAndSay(n),每次都是對前個數字處理,直到達成所需的 n。
方向:
先理解基本規則,確保理解序列的遞推規則,每個數字的描述基於前個數字的字符和它們的連續次數。
模擬生成過程,用一個循環來生成序列,從 countAndSay(1) 開始,逐步生成後續序列,直到達到 n。
計數和描述,在每次生成新序列時,遍歷當前的數字,記錄連續相同字符的次數,再把它按「次數+字符」的格式進行描述。
技巧:
字符串遍歷,要能熟練遍歷字符串並記錄連續相同字符的次數,字符串拼接,把結果照「次數+字符」的格式拼接成新的字符串。
重複運算,因為每個數字都是基於前個數字計算的,所以需要用循環或遞迴來多次生成序列。
步驟:
設初始情況, n = 1 時輸出 "1",從 2 開始,依序生成到 n,每次都對前個序列進行「計數和描述」,最後輸出第 n 個數字的序列。
程式碼構思:
要一個主函數來算 countAndSay(n),且可以用一個輔助函數對每個序列做「計數和描述」。
步驟:
初始化基礎案例,已知 countAndSay(1) 是 "1",這就是初始條件,遞迴生成,從 2 到 n 生成序列,再依次算每個數字的「計數和描述」,輔助函數,用一個輔助函數來處理「計數和描述」,幫助每次生成下一個序列。
程式碼:
class Solution(object):
def countAndSay(self, n):
"""
:type n: int
:rtype: str
"""
#基本情況:當 n = 1 時,返回 "1"
if n == 1:
return "1"

    #初始化起始值
    current = "1"
    
    #從 2 遞迴生成到 n
    for i in range(2, n + 1):
        current = self._next_sequence(current)
    
    return current

def _next_sequence(self, s):
    """
    輔助函數,根據當前的數字序列 s 生成下一個序列
    :type s: str
    :rtype: str
    """
    result = []
    count = 1  # 計數器
    for i in range(1, len(s)):
        if s[i] == s[i - 1]:
            # 如果當前字符與前一個相同,計數器增加
            count += 1
        else:
            # 否則把當前的計數和字符加到結果中,然後重置計數器
            result.append(str(count))
            result.append(s[i - 1])
            count = 1
    
    #別忘了把最後一組字符和計數加到結果中
    result.append(str(count))
    result.append(s[-1])
    
    #把結果列表轉成字符串並返回
    return ''.join(result)

程式碼解析:
基本情況,當 n = 1 ,直接返回 "1"。
遞迴生成,從 2 到 n 迴圈,每次通過 _next_sequence 函數生成下一個數列,_next_sequence 函數,這個輔助函數處理「計數和描述」的邏輯,它遍歷當前序列的每個字符,算連續相同字符的次數,再把結果按格式儲存。
心得:
終於過了一週,沒想到第二天就因為選錯標題而中斷,以我的個性可以繼續這樣寫我自己都覺得有點不可思議,言歸正傳(稍微抱怨一下),這題主要的重點就是理解「Count and Say」序列的規則,也就是每個數字是基於前一個數字進行的描述,程式的困難點在於怎樣正確的處理連續相同字符,再把它按照次數和字符組合成新的序列,而我遇到的困難在於處理連續字符的邏輯,當字符變化時,要把之前的計數結果加到新序列中這讓我搞超久還有,高效拼接字符串,如果對列表和 join 函數不熟練,就會導致性能下降,再來就是循環遞迴,要注意序列的生成是逐層遞迴的,主要是要理解怎麼從一層遞推到下一層。


上一篇
D7:Q30Substring with Concatenation of All Words
下一篇
D9:Q44Wildcard Matching
系列文
Leecode刷題28
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言